-- 运营活动: 幸运购


--[[
{
    cmd_id = 1, -- 命令id，用于批量停止、删除活动 
    act_id = 88, -- 活动id (88 幸运购)
    act_name = "幸运购", -- 活动名称
    act_desc = "每次摇奖都可获取积分，消耗积分兑换奖励！", -- 活动描述
    beg_time = 1493262000,  -- 活动开始时间(unix timestamp)
    end_time = 1593267400,  -- 活动结束时间(unix timestamp)
    config = -- 配置数据
    {
        dailyItems = 
        {
            {type = 0, id = 842, count = 1, bind = 0,},  --第一天团购物品
            {type = 0, id = 852, count = 1, bind = 0,},
            {type = 0, id = 862, count = 1, bind = 0,},
            {type = 0, id = 872, count = 1, bind = 0,},
            {type = 0, id = 1161, count = 1, bind = 0,},
            {type = 0, id = 1162, count = 1, bind = 0,},
            {type = 0, id = 1163, count = 1, bind = 0,},
            {type = 0, id = 1171, count = 1, bind = 0,},
            {type = 0, id = 1172, count = 1, bind = 0,},
            {type = 0, id = 1173, count = 1, bind = 0,},
            {type = 0, id = 1181, count = 1, bind = 0,},
            {type = 0, id = 1188, count = 1, bind = 0,},
            {type = 0, id = 1183, count = 1, bind = 0,},
            {type = 0, id = 1189, count = 1, bind = 0,},
            {type = 0, id = 841, count = 1, bind = 0,},
            {type = 0, id = 851, count = 1, bind = 0,},
            {type = 0, id = 861, count = 1, bind = 0,},
            {type = 0, id = 871, count = 1, bind = 0,},
        },
        dailySpecialItems = 
        {
            {   --第一天特殊奖励
                {type = 0, id = 842, count = 1, bind = 0,},
                {type = 0, id = 852, count = 1, bind = 0,},
                {type = 0, id = 862, count = 1, bind = 0,},
            },
        },
        buyCost = 30, --购买消耗元宝
        AwardTime = 75600, --当天第几秒的时候开奖
        LastBuyCount = 200,     --开奖最低全服购买次数
    },
}
]]

-- 检查配置是否正确，正确则返回 0，否则返回错误码
function oper_act_89_check_cfg(cfg)
    if cfg == nil then return 20 end
    
    local config = cfg.config
    if config == nil then return 21 end
   
   if config.exAwards == nil then return 23 end
   if type(config.exAwards) ~= "table" then return 24 end
   if not oper_act_check_one_award_cfg(config.exAwards) then
        return 22
    end 

   if config.Awards == nil then return 23 end
    if type(config.Awards) ~= "table" then return 24 end
    for idx = 1, #config.Awards do
        local dayRewards = config.Awards[idx]
        if dayRewards == nil then return 25 end
        if type(dayRewards) ~= "table" then return 26 end
        if dayRewards.awards == nil then return 27 end
        if type(dayRewards.awards) ~= "table" then return 28 end
        if not oper_act_check_one_award_cfg(dayRewards.awards) then
            return 22
        end 
    end

    return 0
end


-- 安装活动，成功则返回 0，否则返回错误码
function oper_act_89_setup(cfg) 
    return 0
end

-- 卸载活动
function oper_act_89_unsetup(cfg)   
end

-- 活动开始
function oper_act_89_start(cfg)
    local ssVar = System.getStaticVar()
    ssVar.oper_act_89_start = 1
    ssVar.oper_act_89_cmd = cfg.cmd_id
    ssVar.oper_act_89_act = cfg.act_id

    local data = gRankMgr_GetValueByIndx(0, RANK_DEFINE_OPERATION_89, 1)

    local needClearState = true

    local crossDayState = false

    if data then
        local myData = BaseFuc_unserialize(data)
        if myData and myData.cmd_id and myData.cmd_id == cfg.cmd_id and myData.act_id and myData.act_id == cfg.act_id and
            myData.time and cfg.beg_time <= myData.time and  cfg.end_time > myData.time then
            needClearState = false
            local time = System.getSystemTime()
            if myData and myData.mySelfTime and not System.isUnixTimeSameDay(myData.mySelfTime, time) then
                crossDayState = true
            end
        end
    end

    if crossDayState then
        if cfg then
            local index = oper_act_89_get_day_by_cfg(cfg) - 1
            if index ~= 0 then
                local config = cfg.config
                if config then 
                    local rankPtr = Ranking.getRanking(RankList[RANK_DEFINE_OPERATION_89].strName)
                    local rankCount = Ranking.getRankItemCount(rankPtr)
                    for idx = 1, rankCount do
                        local item = Ranking.getItemFromIndex(rankPtr, idx-1)
                        if item then
                            local actorid = tonumber(Ranking.getId(item))
                            local data = Ranking.getSub(item, 1)
                            local dataTable
                            if not data or data == "" then
                                dataTable = {}
                            else
                                dataTable = BaseFuc_unserialize(data)
                            end
                          
                            if dataTable.myGoldData then
                                local rewardCfg = config.Awards
                                if dataTable.myGoldData[index] and dataTable.myGoldData[index] == 1 then
                                    dataTable.myGoldData[index] = 2

                                    if not dataTable.cmd_id then
                                        dataTable.cmd_id = cfg.cmd_id
                                        dataTable.act_id = cfg.act_id
                                        dataTable.time = time
                                    end

                                    dataTable.mySelfTime = time

                                    local newData = BaseFuc_serialize(dataTable)
                                    gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_89, 1, newData)

                                    local rewards = rewardCfg[index].awards
                                    local title = Lang.ScriptTips.Operation225
                                    local content = string.format(Lang.ScriptTips.Operation226, index)
                                    Awards.GiveToMailById(actorid, rewards, title, content, LogIds.OperationLogId089, Lang.LogTips.Operation089, dataTable.vocation, dataTable.sex)

                                    local sysarg = Actor.getActorById(actorid)
                                    if sysarg then
                                        oper_act_89_packet_data(sysarg, cfg)
                                    end
                                end
                            end
                        end
                    end
                end
            end
        end
    end

    if needClearState then
        gRankMgr_Clear(RANK_DEFINE_OPERATION_89)
    end
end

-- 活动结束
function oper_act_89_end(cfg)
    local ssVar = System.getStaticVar()
    ssVar.oper_act_89_start = nil
    ssVar.oper_act_89_cmd = nil
    ssVar.oper_act_89_act = nil

    if not cfg then return end
    local config = cfg.config
    if not config then return end

    local rankPtr = Ranking.getRanking(RankList[RANK_DEFINE_OPERATION_89].strName)
    local rankCount = Ranking.getRankItemCount(rankPtr)
    for idx = 1, rankCount do
        local item = Ranking.getItemFromIndex(rankPtr, idx-1)
        if item then
            local actorid = tonumber(Ranking.getId(item))
            local data = Ranking.getSub(item, 1)
            local dataTable
            if not data or data == "" then
                dataTable = {}
            else
                dataTable = BaseFuc_unserialize(data)
            end
          
            if dataTable.myGoldData then
                local rewardCfg = config.Awards
                for idx = 1, #config.Awards do
                    if dataTable.myGoldData[idx] and dataTable.myGoldData[idx] == 1 then
                        local rewards = rewardCfg[idx].awards
                        local title = Lang.ScriptTips.Operation225
                        local content = string.format(Lang.ScriptTips.Operation226, idx)
                        Awards.GiveToMailById(actorid, rewards, title, content, LogIds.OperationLogId089, Lang.LogTips.Operation089, dataTable.vocation, dataTable.sex)
                    end
                end
                if dataTable.myExState and dataTable.myExState == 1 then
                    local rewards = config.exAwards
                    local title = Lang.ScriptTips.Operation227
                    local content = Lang.ScriptTips.Operation228
                    Awards.GiveToMailById(actorid, rewards, title, content, LogIds.OperationLogId089, Lang.LogTips.Operation089, dataTable.vocation, dataTable.sex)
                end
            end
        end
    end
end

-- 打包数据
function oper_act_89_packet_data(sysarg, cfg)

    local ssVar = System.getStaticVar()
    if not ssVar.oper_act_89_start then
        return
    end
    if not cfg then return end
    local config = cfg.config
    if not config then return end

    local actorid = Actor.getActorId(sysarg)
    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_89, 1)

    local myData = BaseFuc_unserialize(data)
    

    if not myData then
        myData = {}
    end

    if not myData.myGold then
        myData.myGold = {}
    end
    if not myData.myGoldData then
        myData.myGoldData = {}
    end

    if not myData.myExState then
        myData.myExState = 0
    end


    local pack = oper_act_alloc_init_data_packet(sysarg, cfg.cmd_id, cfg.act_id)
    if (pack == nil) then
        return
    end
    local len = #config.Awards
    DataPack.writeByte(pack, len)
    for idx = 1, len do
        local state = myData.myGoldData[idx] or 0
        DataPack.writeByte(pack, idx)
        DataPack.writeInt(pack, myData.myGold[idx] or 0)
        DataPack.writeByte(pack, state)
    end
    DataPack.writeByte(pack, myData.myExState or 0)
    local index = oper_act_89_get_day_by_cfg(cfg) or 1
    DataPack.writeByte(pack, index)
    DataPack.flush(pack)
    
    --DataPack.writeByte(netPack, 1)        -- 活动特有参数
end

-- 操作，返回操作结果，0为成功
function oper_act_89_do(sysarg, cfg, clientPkt)
    if cfg == nil then return end
    
    if cfg.state == nil or cfg.state ~= 1 then -- 不在活动中
        Actor.sendTipmsg(sysarg,Lang.ScriptTips.Operation001, ttFlyTip)
        return
    end
    
    local config = cfg.config
    if config == nil then -- 参数错误
        print("error, oper_act_89_do cfg.config confg error")
        return
    end
    local ssVar = System.getStaticVar()
    if not ssVar.oper_act_89_start then
        Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation004, ttFlyTip)
        return
    end
    local opType = DataPack.readByte(clientPkt)
    if opType == 1 then
        local Index = DataPack.readByte(clientPkt)
        if Index > #config.Awards then
            Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation005, ttFlyTip)
            return
        end
        local myIndex = oper_act_89_get_day_by_cfg(cfg)
        if Index ~= myIndex then
            Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation229, ttFlyTip)
            return
        end
        local actorid = Actor.getActorId(sysarg)
        local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_89, 1)
        local myData = BaseFuc_unserialize(data)

        if not myData then
            Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation006, ttFlyTip)
            return
        end
        if not myData.myGoldData then
            Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation006, ttFlyTip)
            return
        end
        if not myData.myGoldData[Index] or myData.myGoldData[Index] ~= 1 then
            Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation006, ttFlyTip)
            return
        end

        local rewardCfg = config.Awards

        local rewards = rewardCfg[Index].awards

        myData.myGoldData[Index] = 2
        
        if IsBagGridEnough(sysarg, rewards) then
            GiveCommonAward(sysarg, rewards, LogIds.OperationLogId089, Lang.LogTips.Operation089)
        else
            local actorId = Actor.getActorId(sysarg)
            local title = Lang.ScriptTips.Operation225
            local content = string.format(Lang.ScriptTips.Operation226, Index)

            local sex = Actor.getIntProperty(sysarg, PROP_ACTOR_SEX)
            local vocation = Actor.getIntProperty(sysarg, PROP_ACTOR_VOCATION)
        
            Awards.GiveToMailById(actorId, rewards, title, content, LogIds.OperationLogId089, Lang.LogTips.Operation089, vocation, sex)
        end

        local time = System.getSystemTime()

        if not myData.cmd_id then
            myData.cmd_id = cfg.cmd_id
            myData.act_id = cfg.act_id
            myData.time = time
        end

        myData.mySelfTime = time

        if not myData.sex then
            myData.sex = Actor.getIntProperty(sysarg, PROP_ACTOR_SEX)
            myData.vocation = Actor.getIntProperty(sysarg, PROP_ACTOR_VOCATION)
        end

        local newData = BaseFuc_serialize(myData)
        gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_89, 1, newData)
            
        oper_act_89_packet_data(sysarg, cfg)
    elseif opType == 2 then
        local actorid = Actor.getActorId(sysarg)
        local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_89, 1)
        local myData = BaseFuc_unserialize(data)

        if not myData then
            Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation006, ttFlyTip)
            return
        end
        if not myData.myExState then
            Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation006, ttFlyTip)
            return
        end
        if myData.myExState ~= 1 then
            Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation006, ttFlyTip)
            return
        end

        local rewards = config.exAwards

        myData.myExState = 2
        
        if IsBagGridEnough(sysarg, rewards) then
            GiveCommonAward(sysarg, rewards, LogIds.OperationLogId089, Lang.LogTips.Operation089)
        else
            local actorId = Actor.getActorId(sysarg)
            local title = Lang.ScriptTips.Operation227
            local content = Lang.ScriptTips.Operation228

            local sex = Actor.getIntProperty(sysarg, PROP_ACTOR_SEX)
            local vocation = Actor.getIntProperty(sysarg, PROP_ACTOR_VOCATION)
        
            Awards.GiveToMailById(actorId, rewards, title, content, LogIds.OperationLogId089, Lang.LogTips.Operation089, vocation, sex)
        end

        local time = System.getSystemTime()

        if not myData.cmd_id then
            myData.cmd_id = cfg.cmd_id
            myData.act_id = cfg.act_id
            myData.time = time
        end

        myData.mySelfTime = time

        if not myData.sex then
            myData.sex = Actor.getIntProperty(sysarg, PROP_ACTOR_SEX)
            myData.vocation = Actor.getIntProperty(sysarg, PROP_ACTOR_VOCATION)
        end

        local newData = BaseFuc_serialize(myData)
        gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_89, 1, newData)
            
        oper_act_89_packet_data(sysarg, cfg)
    end
end

-- 跨天
function oper_act_89_new_day_arrive(act_id) 
     local ssVar = System.getStaticVar()
    if not ssVar.oper_act_89_start then
        return
    end
    if not ssVar.oper_act_89_cmd then
        return
    end
    if not ssVar.oper_act_89_act then
        return
    end
    
    local cfg = get_oper_act_cfg(ssVar.oper_act_89_cmd, ssVar.oper_act_89_act)
    if not cfg then
        return
    end

    local config = cfg.config
    if not config then
        return
    end 

    local index = oper_act_89_get_day_by_cfg(cfg) - 1
    if index ~= 0 then
        local rankPtr = Ranking.getRanking(RankList[RANK_DEFINE_OPERATION_89].strName)
        local rankCount = Ranking.getRankItemCount(rankPtr)
        for idx = 1, rankCount do
            local item = Ranking.getItemFromIndex(rankPtr, idx-1)
            if item then
                local actorid = tonumber(Ranking.getId(item))
                local data = Ranking.getSub(item, 1)
                local dataTable
                if not data or data == "" then
                    dataTable = {}
                else
                    dataTable = BaseFuc_unserialize(data)
                end
              
                if dataTable.myGoldData then
                    local rewardCfg = config.Awards
                    if dataTable.myGoldData[index] and dataTable.myGoldData[index] == 1 then
                        dataTable.myGoldData[index] = 2

                        if not dataTable.cmd_id then
                            dataTable.cmd_id = cfg.cmd_id
                            dataTable.act_id = cfg.act_id
                            dataTable.time = time
                        end

                        dataTable.mySelfTime = time

                        local newData = BaseFuc_serialize(dataTable)
                        gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_89, 1, newData)

                        local rewards = rewardCfg[index].awards
                        local title = Lang.ScriptTips.Operation225
                        local content = string.format(Lang.ScriptTips.Operation226, index)
                        Awards.GiveToMailById(actorid, rewards, title, content, LogIds.OperationLogId089, Lang.LogTips.Operation089, dataTable.vocation, dataTable.sex)

                        local sysarg = Actor.getActorById(actorid)
                        if sysarg then
                            oper_act_89_packet_data(sysarg, cfg)
                        end
                    end
                end
            end
        end
    end
end

--累计充值元宝
function oper_act_89_withdrawyuanbao(sysarg, Gold)
    local ssVar = System.getStaticVar()
    if not ssVar.oper_act_89_start then
        return
    end
    if not ssVar.oper_act_89_cmd then
        return
    end
    if not ssVar.oper_act_89_act then
        return
    end
    
    local cfg = get_oper_act_cfg(ssVar.oper_act_89_cmd, ssVar.oper_act_89_act)
    if not cfg then
        return
    end

    local config = cfg.config
    if not config then
        return
    end 

    local index = oper_act_89_get_day_by_cfg(cfg)

    local actorid = Actor.getActorId(sysarg)
    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_89, 1)

    local myData = BaseFuc_unserialize(data)

    if not myData then
        myData = {}
    end
    if not myData.myGold then
        myData.myGold = {}
    end

    if not myData.myGold[index] then
        myData.myGold[index] = 0
    end

    myData.myGold[index] = myData.myGold[index] + Gold

    if not myData.myGoldData then
        myData.myGoldData = {}
    end

    if not myData.myGoldData[index] then
        myData.myGoldData[index] = 0
    end

    if not myData.myExState then
        myData.myExState = 0
    end

    if config.Awards[index] and config.Awards[index].dailyRechargeNum and myData.myGold[index] >= config.Awards[index].dailyRechargeNum and myData.myGoldData[index] == 0 then
        myData.myGoldData[index] = 1
    end

    local state = true
    for idx = 1, #config.Awards do
        if not myData.myGoldData[idx] or myData.myGoldData[idx] < 1 then
            state = false
        end
    end

    if state and myData.myExState == 0 then
        myData.myExState = 1
    end

    local time = System.getSystemTime()

    if not myData.cmd_id then
        myData.cmd_id = cfg.cmd_id
        myData.act_id = cfg.act_id
        myData.time = time
    end

    myData.mySelfTime = time

    if not myData.sex then
        myData.sex = Actor.getIntProperty(sysarg, PROP_ACTOR_SEX)
        myData.vocation = Actor.getIntProperty(sysarg, PROP_ACTOR_VOCATION)
    end

    local newData = BaseFuc_serialize(myData)
    gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_89, 1, newData)
    oper_act_89_packet_data(sysarg, cfg)
end

function oper_act_89_get_day_by_cfg(cfg)
    local index = 1
    local time = System.getSystemTime()
    local second = System.getCurrMiniTime() - System.getToday()
    local zeroTime = time - second
    if zeroTime > cfg.beg_time then
        index = math.floor((zeroTime - cfg.beg_time) / 86400) + 1
        if (zeroTime - cfg.beg_time) % 86400 ~= 0 then
            index = index + 1
        end
    end

    return index
end

